<?php
/**
 * 认证相关函数
 * 处理管理员登录、验证等功能
 */

/**
 * 检查是否已登录
 * @return bool 是否已登录
 */
function isLoggedIn() {
    // 确保session已启动
    if (session_status() === PHP_SESSION_NONE) {
        return false;
    }

    // 检查基本的登录状态
    if (!isset($_SESSION['admin_logged_in']) || $_SESSION['admin_logged_in'] !== true) {
        return false;
    }

    // 检查用户名是否存在
    if (!isset($_SESSION['admin_username']) || empty($_SESSION['admin_username'])) {
        writeLog("Session中缺少用户名信息，强制登出", 'WARNING');
        doLogout();
        return false;
    }

    // 检查session完整性
    $loginTime = $_SESSION['login_time'] ?? 0;
    $currentTime = time();

    // 检查登录时间是否合理（防止session劫持）
    if ($currentTime - $loginTime > 86400) {
        writeLog("Session已过期，自动登出", 'INFO');
        doLogout();
        return false;
    }

    // 检查登录时间是否为未来时间（防篡改）
    if ($loginTime > $currentTime) {
        writeLog("检测到登录时间为未来时间，可能存在session篡改", 'ERROR');
        doLogout();
        return false;
    }

    // 检查最后活动时间
    $lastActivity = $_SESSION['last_activity'] ?? $loginTime;
    if ($currentTime - $lastActivity > 3600) { // 1小时无活动
        writeLog("用户长时间无活动，需要重新验证", 'WARNING');
        // 不强制登出，只记录警告
        $_SESSION['last_activity'] = $currentTime;
    }

    // 检查最后活动时间是否为未来时间（防篡改）
    if ($lastActivity > $currentTime) {
        writeLog("检测到最后活动时间为未来时间，可能存在session篡改", 'ERROR');
        doLogout();
        return false;
    }

    // 检查session ID是否匹配
    if (isset($_SESSION['session_id']) && $_SESSION['session_id'] !== session_id()) {
        writeLog("Session ID不匹配，可能存在会话劫持", 'ERROR');
        doLogout();
        return false;
    }

    // 验证用户代理（可选的安全措施）
    if (isset($_SESSION['user_agent']) && $_SESSION['user_agent'] !== ($_SERVER['HTTP_USER_AGENT'] ?? '')) {
        writeLog("检测到用户代理变化，可能存在安全风险", 'ERROR');
        doLogout();
        return false;
    }

    return true;
}

/**
 * 验证登录信息
 * @param string $username 用户名
 * @param string $password 密码
 * @return bool 是否验证成功
 */
function validateLogin($username, $password) {
    // 优先使用数据库设置，如果不存在则使用配置文件
    try {
        require_once dirname(__FILE__) . '/database.php';
        $db = new Database();
        $settings = $db->getSettings();
        $adminUsername = $settings['admin_username'] ?? ADMIN_USERNAME;
        $adminPassword = $settings['admin_password'] ?? ADMIN_PASSWORD;
        return $username === $adminUsername && $password === $adminPassword;
    } catch (Exception $e) {
        // 如果数据库访问失败，回退到配置文件
        writeLog("数据库访问失败，使用配置文件验证: " . $e->getMessage(), 'WARNING');
        return $username === ADMIN_USERNAME && $password === ADMIN_PASSWORD;
    }
}

/**
 * 执行登录
 * @param string $username 用户名
 * @param string $password 密码
 * @return bool 是否登录成功
 */
function doLogin($username, $password) {
    if (validateLogin($username, $password)) {
        // 确保session已正确初始化
        if (session_status() === PHP_SESSION_NONE) {
            initSession();
        }

        // 设置session数据
        $_SESSION['admin_logged_in'] = true;
        $_SESSION['admin_username'] = $username;
        $_SESSION['login_time'] = time();
        $_SESSION['login_ip'] = getClientIP();
        $_SESSION['last_activity'] = time();
        $_SESSION['session_id'] = session_id();
        $_SESSION['user_agent'] = $_SERVER['HTTP_USER_AGENT'] ?? '';

        // 重新生成session ID防止会话固定攻击
        session_regenerate_id(true);

        // 更新session ID到session中
        $_SESSION['session_id'] = session_id();

        writeLog("管理员登录成功: $username, IP: " . getClientIP() . ", Session ID: " . session_id());
        return true;
    }

    writeLog("管理员登录失败: $username, IP: " . getClientIP(), 'WARNING');
    return false;
}

/**
 * 执行登出
 */
function doLogout() {
    $username = $_SESSION['admin_username'] ?? 'unknown';
    writeLog("管理员登出: $username, IP: " . getClientIP());

    // 清除所有session变量
    session_unset();

    // 销毁session文件
    session_destroy();

    // 删除session cookie
    if (ini_get("session.use_cookies")) {
        $params = session_get_cookie_params();
        setcookie(session_name(), '', time() - 42000,
            $params["path"], $params["domain"],
            $params["secure"], $params["httponly"]
        );
    }
}

/**
 * 检查登录状态，未登录则跳转
 * @param string $redirectUrl 跳转地址
 */
function requireLogin($redirectUrl = null) {
    // 强制确保session已正确初始化
    if (session_status() === PHP_SESSION_NONE) {
        initSession();
    }

    // 再次验证session状态
    if (session_status() === PHP_SESSION_NONE) {
        writeLog("Session初始化失败，强制拒绝访问", 'ERROR');
        die('System Error: Session initialization failed');
    }

    // 强化的登录检查
    if (!isLoggedIn() || !isset($_SESSION['admin_logged_in']) || $_SESSION['admin_logged_in'] !== true) {
        // 记录访问尝试
        $currentUrl = $_SERVER['REQUEST_URI'] ?? 'unknown';
        writeLog("未登录用户尝试访问受保护页面: $currentUrl, IP: " . getClientIP(), 'WARNING');

        // 清除可能损坏的session数据
        unset($_SESSION['admin_logged_in']);
        unset($_SESSION['admin_username']);
        unset($_SESSION['login_time']);
        unset($_SESSION['last_activity']);

        if ($redirectUrl === null) {
            $redirectUrl = getUrl('admin/login');
        }

        // 检查是否是登录页面本身，避免无限循环
        $loginPage = getUrl('admin/login');
        $isLoginPage = (strpos($currentUrl, '/admin/login') !== false);

        if ($isLoginPage) {
            // 如果已经在登录页面，不要再次跳转，直接返回
            return;
        }

        // 添加返回URL参数，方便登录后跳转回原页面
        $returnUrl = urlencode($currentUrl);
        header("Location: $redirectUrl?return=" . $returnUrl);
        exit;
    }

    // 额外的安全验证
    $loginTime = $_SESSION['login_time'] ?? 0;
    $currentTime = time();
    if ($currentTime - $loginTime > 86400) {
        writeLog("Session已过期，强制登出", 'INFO');
        doLogout();
        $redirectUrl = getUrl('admin/login');
        header("Location: $redirectUrl?expired=1");
        exit;
    }

    // 更新最后活动时间
    $_SESSION['last_activity'] = time();
}

/**
 * 生成CSRF令牌
 * @return string CSRF令牌
 */
function generateCsrfToken() {
    if (!isset($_SESSION['csrf_token'])) {
        $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
    }
    return $_SESSION['csrf_token'];
}

/**
 * 验证CSRF令牌
 * @param string $token 提交的令牌
 * @return bool 是否验证成功
 */
function validateCsrfToken($token) {
    return isset($_SESSION['csrf_token']) && hash_equals($_SESSION['csrf_token'], $token);
}

/**
 * 获取登录页面HTML
 * @param string $error 错误消息
 * @return string HTML内容
 */
function getLoginPageHtml($error = '') {
    $csrfToken = generateCsrfToken();
    // 保留之前输入的用户名（登录失败时）
    $previousUsername = htmlspecialchars($_POST['username'] ?? '');
    
    // 获取动态网站标题
    try {
        require_once dirname(__FILE__) . '/database.php';
        $db = new Database();
        $settings = $db->getSettings();
        $siteTitle = $settings['site_title'] ?? SITE_TITLE;
    } catch (Exception $e) {
        $siteTitle = SITE_TITLE;
    }
    
    return '<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>管理员登录 - ' . $siteTitle . '</title>
    <link rel="stylesheet" href="' . asset('css/admin.css') . '">
    <link rel="stylesheet" href="' . asset('libs/fontawesome/all.min.css') . '">
</head>
<body class="login-page">
    <div class="login-container">
        <div class="login-card">
            <div class="login-header">
                <h1><i class="fas fa-user-shield"></i> 管理员登录</h1>
                <p>请输入您的登录凭据</p>
            </div>
            
            ' . ($error ? '<div class="alert alert-error"><i class="fas fa-exclamation-triangle"></i> ' . htmlspecialchars($error) . '</div>' : '') . '
            
            <form method="POST" class="login-form">
                <input type="hidden" name="csrf_token" value="' . $csrfToken . '">
                
                <div class="form-group">
                    <label for="username"><i class="fas fa-user"></i> 用户名</label>
                    <input type="text" id="username" name="username" value="' . $previousUsername . '" required autofocus>
                </div>
                
                <div class="form-group">
                    <label for="password"><i class="fas fa-lock"></i> 密码</label>
                    <input type="password" id="password" name="password" required>
                </div>
                
                <button type="submit" class="btn btn-primary btn-block">
                    <i class="fas fa-sign-in-alt"></i> 登录
                </button>
            </form>
            
            <div class="login-footer">
                <a href="' . getUrl() . '" class="back-link">
                    <i class="fas fa-arrow-left"></i> 返回首页
                </a>
            </div>
        </div>
    </div>
    
    <script src="' . asset('js/admin.js') . '"></script>
</body>
</html>';
}

/**
 * 处理登录表单提交
 * @return array 处理结果
 */
function handleLoginForm() {
    if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
        return ['success' => false, 'message' => '无效的请求方法'];
    }

    // 验证CSRF令牌
    $csrfToken = $_POST['csrf_token'] ?? '';
    if (!validateCsrfToken($csrfToken)) {
        return ['success' => false, 'message' => 'CSRF验证失败'];
    }

    $username = sanitizeInput($_POST['username'] ?? '');
    $password = $_POST['password'] ?? '';

    if (empty($username) || empty($password)) {
        return ['success' => false, 'message' => '用户名和密码不能为空'];
    }

    if (doLogin($username, $password)) {
        return ['success' => true, 'message' => '登录成功'];
    } else {
        return ['success' => false, 'message' => '用户名或密码错误'];
    }
}

/**
 * 获取管理员信息
 * @return array 管理员信息
 */
function getAdminInfo() {
    return [
        'username' => $_SESSION['admin_username'] ?? '',
        'login_time' => $_SESSION['login_time'] ?? 0,
        'is_logged_in' => isLoggedIn()
    ];
} 